import './index.scss'
import { MapBar, StatusBar, ChatBar, ChatLogItem } from "./UI/ui"
import { DataSegment } from './datastructure/DataSegment'
import { IM } from './IM/im'
import { ChatInfoItem } from './UI/chat_bar/ChatBar'
import * as TOOL from './UI/tool'
import $ = require("jquery");
import { JSEncrypt } from 'jsencrypt'

class Index {
    status_bar: StatusBar;
    map_bar: MapBar;
    chat_bar: ChatBar;
    im: IM;
    constructor() {
        this.status_bar = new StatusBar();
        this.map_bar = new MapBar();
        this.chat_bar = new ChatBar();
        this.im = new IM(TOOL.getWebSocketAddress());

        this.chat_bar.inPut.sendChatMessage = this.im.sendChatMessage.bind(this.im);
        this.chat_bar.inPut.sendCommand = this.im.sendCommand.bind(this.im);
        this.chat_bar.chatLog.sendOnline = this.im.sendOnline.bind(this.im);
        this.chat_bar.inPut.sendLocalCommand = this.map_bar.devConsole.bind(this.map_bar);

        this.im.onChat = this.chat_bar.onChat.bind(this.chat_bar);
        this.im.onInstruct = this.chat_bar.onInstruct.bind(this.chat_bar);
        this.im.onOnline = this.chat_bar.onOnline.bind(this.chat_bar);
        this.im.onStatus = this.status_bar.onStatus.bind(this.status_bar);
        this.im.onMap = this.map_bar.onMap.bind(this.map_bar);

        this.status_bar.onMessageSend = this.im.sendStatus.bind(this.im);

        this.map_bar.onMessageSend = this.im.sendMap.bind(this.im);
    }
    resize(height: number, width: number) {
        this.status_bar.resize(height, width);
        this.map_bar.resize(height, width);
        this.chat_bar.resize(height, width);
    };
    connectServer(room: string, time: number) {
        setTimeout(async () => {
            try {
                this.chat_bar.addChatItem(new ChatInfoItem("正在与服务器链接", "secondary"));
                let ans = await this.im.handShake(room);
                let code = ans.get("code");
                if (code == "0") {
                    time = 1;
                    this.chat_bar.chatLog.clear();
                    this.chat_bar.addChatItem(new ChatInfoItem("与服务器链接成功", "success"));
                    //StatusBar状态获取
                    this.status_bar.onMessageSend("update");
                    while (true) {
                        await this.im.work();
                    }
                } else {
                    let why = ans.get("why");
                    this.chat_bar.addChatItem(new ChatInfoItem(`与服务器链接失败, 原因 ${why}`, "danger"));
                }
            } catch (e) {
                let code = e.code;
                switch (code) {
                    case 1000:
                        this.chat_bar.addChatItem(new ChatInfoItem(`服务器主动关闭了链接`, "danger"));
                        return;
                    case 1001:
                        this.chat_bar.addChatItem(new ChatInfoItem(`你放弃了链接,请刷新页面`, "danger"));
                        return;
                    case 1011:
                        time += 10;
                        this.chat_bar.addChatItem(new ChatInfoItem(`服务器出现了错误请立刻联系管理员, 将在 ${time} 秒钟后重连`, "danger"));
                        break;
                    case undefined:
                        this.chat_bar.addChatItem(new ChatInfoItem(`服务器没有开机,或你没有链接网络, 或者出现了内部问题, 将在 ${time} 秒钟后重连`, "danger"));
                        break;
                    default:
                        this.chat_bar.addChatItem(new ChatInfoItem(`出现了严重的协议问题,请检查你的网络,将在 ${time} 秒钟后重连`, "danger"));
                        break;
                }
                setTimeout(() => {
                    this.connectServer(room, time * 2);
                }, time * 1000)
            }
        }, time);
    }
    start() {
        document.body.appendChild(this.status_bar.element!);
        document.body.appendChild(this.map_bar.element!);
        document.body.appendChild(this.chat_bar.element);
        this.resize(window.innerHeight, window.innerWidth);
        window.addEventListener("resize", () => this.resize(window.innerHeight, window.innerWidth));
    }
}

let inputUsername = (document.getElementById("inputUsername") as HTMLInputElement);
let inputPassword = (document.getElementById("inputPassword") as HTMLInputElement);
let inputRoom = (document.getElementById("inputRoom") as HTMLInputElement);
let loginButton = document.getElementById("loginButton") as HTMLButtonElement;

let user = window.localStorage.getItem("name");
let publicKey = window.localStorage.getItem("publicKey");
let privateKey = window.localStorage.getItem("privateKey");

if (user && publicKey && privateKey) {
    // 当前已经有一个登录了的用户
    inputUsername.disabled = true;
    inputUsername.value = user;
    inputPassword.style.display = "none";
    (document.getElementById("register") as HTMLAnchorElement).href = "#";
    (document.getElementById("register") as HTMLAnchorElement).innerText = "登出";
    (document.getElementById("register") as HTMLAnchorElement).onclick = () => {
        window.localStorage.removeItem("publicKey");
        window.localStorage.removeItem("privateKey");
        window.localStorage.removeItem("name");
        location.reload();
    }
    loginButton.onclick = () => {
        let index = new Index();
        index.start();
        $("#loginbody").fadeOut(2000);
        index.connectServer(inputRoom.value, 1);
    }
} else {
    loginButton.onclick = () => {
        $.get("love/getRandom.do", async (random) => {
            let crypt = new JSEncrypt({ default_key_size: 2048 });
            let encrypt = new JSEncrypt({ default_key_size: 2048 });
            encrypt.setPublicKey(TOOL.setverPublicKey);


            loginButton.innerText = "生成密钥中.";
            let isdone = false;
            setTimeout(function load() {
                loginButton.innerText += ".";
                if (!isdone) {
                    setTimeout(load, 500);
                }
            }, 500);
            crypt.getKey(async function () {
                let privateKey = crypt.getPrivateKey();
                let publicKey = crypt.getPublicKey();
                let password = await TOOL.sha256(inputPassword.value);
                let encryptedPassword = encrypt.encrypt(random + password);
                $.post("love/userLogin.do", {
                    name: inputUsername.value,
                    password: encryptedPassword,
                    publicKey: publicKey
                }, (data) => {
                    isdone = true;
                    switch (data) {
                        case "RANDOM_NOT_INIT":
                            alert("不可能发生");
                            break;
                        case "RANDOM_INCORRECT":
                            alert("随机数出现错误, 请尝试刷新");
                            break;
                        case "SUCCESS":
                            window.localStorage.setItem("publicKey", publicKey);
                            window.localStorage.setItem("privateKey", privateKey);
                            window.localStorage.setItem("name", inputUsername.value);
                            let index = new Index();
                            index.start();
                            $("#loginbody").fadeOut(2000);
                            index.connectServer(inputRoom.value, 1);
                            break;
                        case "INCORRECT_NAME_OR_PASSWORD":
                            alert("不正确的用户名或密码");
                            break;
                        case "RAS_CHIPHER_ERROR":
                            alert("不正确的服务器公钥, 请注意是否被监听");
                            break;
                    }
                });
            });

        })
    }
}

